package ru.rchervot.sanasar.client.view;

import ru.rchervot.sanasar.client.event.EventPageChange;
import ru.rchervot.sanasar.client.event.HandlerPageChange;
import ru.rchervot.sanasar.client.model.ResultsPage;
import ru.rchervot.sanasar.client.model.SearchResultsItem;
import ru.rchervot.sanasar.client.rpc.GetPage;
import ru.rchervot.sanasar.client.rpc.GotPage;
import ru.rchervot.sanasar.client.rpc.RPCServiceAsync;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.shared.HandlerManager;

public abstract class AbstractRecordFooterPresenter implements RecordFooterPresenter {
	
	private final HandlerManager eventBus;
	private final RPCServiceAsync service;
	private final Display display;
	private ResultsPage<SearchResultsItem> currentPage;
	
	public AbstractRecordFooterPresenter(Display display, HandlerManager eventBus,
			RPCServiceAsync service) {
		this.eventBus = eventBus;
		this.display = display;
		this.service = service;
		
		listenForPageChange();
		
		handleNextItemClick();
		handlePrevItemClick();
		handleItemBoxEnterKeyPress();
  }
	
	@Override
	public void bindDisplay() {
		display.setPresenter(this);
	}
    
  private void listenForPageChange() {
		eventBus.addHandler(EventPageChange.getType(),
				new HandlerPageChange<SearchResultsItem>() {
			@Override
			public void onPageChange(
					EventPageChange<SearchResultsItem> event) {		
				currentPage = event.getPage();
				if (event.isStartPage()) {
					disableButons();
				} else {
					if (event.getPage().isEmpty()) {
						disableButons();
					} else {
						setButtonsVisibility(event.getPage());					
					}					
				}
			}
		});
	}
  
  private void disableButons() {
  	display.setEnabledButtonPrev(false);
  	display.setEnabledButtonNext(false);
  	display.setEnabledItemBox(false);
  	
  	display.getItemBoxValue().setValue("");
  }
  
  private void setButtonsVisibility(ResultsPage<SearchResultsItem> page) {
		if (page.isCurrentOffsetFirst()) {
			display.setEnabledButtonPrev(false);
		} else {
			display.setEnabledButtonPrev(true);
		}

		if (page.isCurrentOffsetLast()) {
			display.setEnabledButtonNext(false);
		} else {
			display.setEnabledButtonNext(true);
		}
	
		display.setEnabledItemBox(true);
		display.getItemBoxValue().setValue(String.valueOf(page.getOffsetForHumans()));
	}
  
  private void handleNextItemClick() {
  	display.getNextItemButton().addClickHandler(new ClickHandler() {
  		@Override
  		public void onClick(ClickEvent event) {
  			if(currentPage.isCurrentRowLast()) {
  				askServiceForNewPage(currentPage.getOffset() + 1);
  			} else {
  				currentPage.increaseOffset();
  				eventBus.fireEvent(EventPageChange.build(currentPage));
  			}
  		}
  	});
  }
  
  private void handlePrevItemClick() {
  	display.getPrevItemButton().addClickHandler(new ClickHandler() {
  		@Override
  		public void onClick(ClickEvent event) {
  			if(currentPage.isCurrentRowFirst()) {
  						askServiceForNewPage(currentPage.getOffset() - 1);
  			} else {
  				currentPage.decreaseOffset();
  				eventBus.fireEvent(EventPageChange.build(currentPage));
  			}
  		}
  	});
  }
  
  private void handleItemBoxEnterKeyPress() {
  	display.getItemBox().addKeyPressHandler(new KeyPressHandler() {
      public void onKeyPress(KeyPressEvent event) {
      	if ((event.getCharCode() == 13) && (! event.isAnyModifierKeyDown())) {
      		int offset = 0;
      		
      		try {
      			offset = Integer.valueOf(display.getItemBoxValue().getValue());
      			offset -= 1; //because this offset comes from humans
      		} catch (Exception ex) {
      			System.out.println("ItemBoxValue is not integer");
      		}
      		
      		if(currentPage.isContainOffset(offset)) {
      			currentPage.setOffset(offset);
      			eventBus.fireEvent(EventPageChange.build(currentPage));
      		} else {
      			askServiceForNewPage(offset);
      		}
      	}
      }
    });
  }
  
  private void askServiceForNewPage(int offset) {
  	service.execute(
				new GetPage(currentPage.getQueryID(), offset),
						new GotPage<SearchResultsItem>() {
					@Override
					public void got(
							ResultsPage<SearchResultsItem> resultsPage) {
					}
				});
  }
  
}
